﻿using System;
using System.Linq;
using Caliburn.Micro;

namespace YiJing.Model
{
    public sealed class CoinSet : PropertyChangedBase
    {
        private readonly Coin[] _coins;
        private bool _notificationsSuspended;

        public CoinSet(int count)
        {
            _coins = new Coin[count];

            for (var i = 0; i < count; ++i)
            {
                var coin = new Coin();
                coin.CoinFlipped += delegate { OnCoinFlipped(); };

                Coins[i] = coin;
            }
        }

        public Coin[] Coins
        {
            get { return _coins; }
        }

        public int HeadsCount
        {
            get { return Coins.Count(coin => coin.IsHeadUp); }
            set
            {
                if (value == HeadsCount) return;
                Guard.Against<ArgumentOutOfRangeException>(value < 0 || value > Coins.Length, "Heads");

                _notificationsSuspended = true;
                
                if (HeadsCount > value)
                {
                    foreach (var coin in Coins.Reverse().TakeWhile(coin => HeadsCount != value).Where(coin => coin.IsHeadUp))
                        coin.IsHeadUp = false;
                }
                else
                {
                    foreach (var coin in Coins.TakeWhile(coin => HeadsCount != value).Where(coin => !coin.IsHeadUp))
                        coin.IsHeadUp = true;
                }

                _notificationsSuspended = false;
                OnCoinFlipped();
            }
        }

        public int TailsCount
        {
            get { return Coins.Length - HeadsCount; }
            set { HeadsCount = Coins.Length - value; }
        }

        private void OnCoinFlipped()
        {
            if (_notificationsSuspended) return;
            NotifyOfPropertyChange(() => HeadsCount);
            NotifyOfPropertyChange(() => TailsCount);
        }
    }
}